package common.utils.traingenerate;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import common.utils.GetAllFilesOfDir;

/**
 * Se encarga de generar los archivos para entrenar la red y los utilizados para probar la misma
 * en base a los archivos con los coeficientes de mfcc obtenidos.
 * @author Martin
 *
 */
public class GenerarEntradas {

	private String dirCoefSeparados = "D:/WAVS_TO_COEF/Naty/Prueba3/individuales/";
	private String dirArchGenerados = "d:/WAVS_TO_COEF/Naty/Prueba3/generados/";
	
	private static final Logger  logger  = Logger.getLogger(GenerarEntradas.class);

	
	public GenerarEntradas(){
		
	}
	
	
	/**
	 * Genera los archivos pero sin hacer la segunda normalizacion, 
	 * solo toma un coeficiente de los 13 que saca 
	 * @param args
	 */
	public void procesar(Integer cantOfCoef) {
		
		GetAllFilesOfDir g=new GetAllFilesOfDir();
		
		//lista que contendra todos los directorios de los cuales obtuve parametros, y tengo que procesar
		List<File> directorios=new ArrayList<File>();
		
		directorios.addAll(
				g.getListNameOfDirInDir( 
						dirCoefSeparados,
						new FilenameFilter() {
							public boolean accept(File dir, String name){
								return (name.endsWith("Coef"));	
							}
						}
				)
		);
		
		logger.info("Obtenemos datos de los siguientes directorios de coeficientes: ");
		for (int i = 0; i < directorios.size(); i++) {
			logger.info(directorios.get(i).getAbsolutePath());
		}
		
		File dirArchGen = new File(dirArchGenerados);
		if (!dirArchGen.exists()){
			dirArchGen.mkdirs();
		}
		
		try {
		
			logger.info("**************************************************************************************");
			for (Integer i=1;i<=cantOfCoef;i++){
				final Integer h=i;
				String dirCoef=dirArchGenerados+"coef"+i;
				
				logger.info("CREAMOS LOS ARCHIVOS PARA EL COEFICIENTE "+i);
				
				File dirCreated = new File(dirCoef);
				if (!dirCreated.exists()){
					dirCreated.mkdir();
				}
	
				//creo los archivos que usa la red
				File fileParaEntrenar=new File(dirCoef+"/paraentrenar.txt");
				if (!fileParaEntrenar.exists()){ fileParaEntrenar.createNewFile(); }
				File fileParaEntrenarResultados=new File(dirCoef+"/paraentrenarresultados.txt");
				if (!fileParaEntrenarResultados.exists()){ fileParaEntrenarResultados.createNewFile(); } 
				File fileParaProbar=new File(dirCoef+"/paraprobar.txt");
				if (!fileParaProbar.exists()){ fileParaProbar.createNewFile(); } 
				File fileParaProbarResultados=new File(dirCoef+"/paraprobarresultados.txt");
				if (!fileParaProbarResultados.exists()){ fileParaProbarResultados.createNewFile(); } 
				File fileErrores=new File(dirCoef+"/errores.txt");
				if (!fileErrores.exists()){ fileErrores.createNewFile(); } 
		
				FileOutputStream writerParaEntrenar = new FileOutputStream(fileParaEntrenar);
				FileOutputStream writerParaEntrenarResultados = new FileOutputStream(fileParaEntrenarResultados);
				FileOutputStream writerParaProbar = new FileOutputStream(fileParaProbar);
				FileOutputStream writerParaProbarResultados = new FileOutputStream(fileParaProbarResultados);
					
			
				//recorro los directorios de las palabras que quiero agregar en los archivos
				for (File dir:directorios){
					
					//obtengo el nombre de la palabra al cual pertenece el directorio
					String palabra = dir.getName().substring(0,dir.getName().length()-4);
					String palabraResult = getResult(palabra);
					
					//obtengo el archivo del coeficiente que estoy procesando, dentro del directorio actual
					File archivoCoef=g.getNameOfFilesInDir(
										dir,
										new FilenameFilter() {
											public boolean accept(File dir, String name){
												return (name.contains("coef"+h.toString()+".txt"));	
											}
										}
								);
					
					
					System.out.println("procesando arch:" + dir.getAbsolutePath()+" perteneciente a la palabra "+palabra);
					
					FileReader fr = new FileReader(archivoCoef);
					BufferedReader bf = new BufferedReader(fr);
					
					String sCadena=null;
	
					int numberOfLines = getNumberOfLines(archivoCoef.getAbsolutePath());
					
					logger.info("Proceso el archivo: "+ archivoCoef.getAbsolutePath()+" que tiene "+numberOfLines+" lineas.");
					
					int lineasProcesadas = 0;
					while ((sCadena = bf.readLine())!=null) {

						//para entrenar
						if (lineasProcesadas <= numberOfLines - 10 ){
							
							writerParaEntrenar.write(sCadena.getBytes());
							writerParaEntrenar.write("\n".getBytes());
							
							writerParaEntrenarResultados.write(palabraResult.getBytes());
							writerParaEntrenarResultados.write("\n".getBytes());
	
						}
						//para probar
						if (lineasProcesadas > numberOfLines - 10){
							
							writerParaProbar.write(sCadena.getBytes());
							writerParaProbar.write("\n".getBytes());				
			
							writerParaProbarResultados.write(palabraResult.getBytes());
							writerParaProbarResultados.write("\n".getBytes());				
			
						}
						lineasProcesadas++;			
						
					}
				}
				
				
				//cierro los archivos
				writerParaEntrenar.flush();
				writerParaEntrenar.close();
				writerParaEntrenarResultados.flush();
				writerParaEntrenarResultados.close();
				writerParaProbar.flush();
				writerParaProbar.close();
				writerParaProbarResultados.flush();
				writerParaProbarResultados.close();
				
				logger.info("Se creo el archivo: "+ fileParaEntrenar.getAbsolutePath()+" para el coeficiente actual.");
				logger.info("Se creo el archivo: "+ fileParaEntrenarResultados.getAbsolutePath()+" para el coeficiente actual.");
				logger.info("Se creo el archivo: "+ fileParaProbar.getAbsolutePath()+" para el coeficiente actual.");
				logger.info("Se creo el archivo: "+ fileParaProbarResultados.getAbsolutePath()+" para el coeficiente actual.");
				logger.info("Se creo el archivo: "+ fileErrores.getAbsolutePath()+" para el coeficiente actual.");
				logger.info("**************************************************************************************");
				
			}
		}catch (Exception e) {
			// TODO: handle exception
		}
		
		
	}

	private int getNumberOfLines(String absolutePath) {
		int lNumeroLineas = 0;
		try{
			FileReader fr = new FileReader(absolutePath);
			BufferedReader bf = new BufferedReader(fr);
			String sCadena;
			while ((sCadena = bf.readLine())!=null) {
			  lNumeroLineas++;
			}
			bf.close();
			fr.close();
		} catch (FileNotFoundException fnfe){
			fnfe.printStackTrace();
		} catch (IOException ioe){
			ioe.printStackTrace();
		}
		
		return lNumeroLineas;
	}


	/**
	 * Le paso el coeficiente y me dice el resultado esperado
	 * @return
	 */
	private String getResult(String palabra){

		if (palabra.startsWith("luz")){
			return "0.0;0.0;1.0";
		}
		if (palabra.startsWith("tv")){
			return "0.0;1.0;1.0";
		}
		if (palabra.startsWith("radio")){
			return "0.0;1.0;0.0";
		}
		if (palabra.startsWith("cerrar")){
			return "1.0;0.0;1.0";
		}
		if (palabra.startsWith("persiana")){
			return "1.0;1.0;1.0";
		}
		
		return "0.0;0.0;0.0";
		
		
	}
}
